﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;
using Microsoft.CSharp.RuntimeBinder;

namespace SystemDiagramNew
{
	public static class ExtensibleStorageManager
	{
		public static Schema CreateSchema()
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.m_GUID);
			if (schema != null)
			{
				return schema;
			}
			SchemaBuilder schemaBuilder = new SchemaBuilder(ExtensibleStorageManager.m_GUID);
			schemaBuilder.SetSchemaName(ExtensibleStorageManager.m_schemaName);
			FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField("Diameter", typeof(double));
			fieldBuilder.SetUnitType(0);
			FieldBuilder fieldBuilder2 = schemaBuilder.AddSimpleField("StartElevation", typeof(double));
			fieldBuilder2.SetUnitType(0);
			FieldBuilder fieldBuilder3 = schemaBuilder.AddSimpleField("EndElevation", typeof(double));
			fieldBuilder3.SetUnitType(0);
			FieldBuilder fieldBuilder4 = schemaBuilder.AddSimpleField("LegendScale", typeof(double));
			fieldBuilder4.SetUnitType(0);
			return schemaBuilder.Finish();
		}

		public static void WritePipeExtensibleStorageToDetailCurve(Pipe pipe, DetailCurve curve, double legendScale)
		{
			Schema schema = ExtensibleStorageManager.CreateSchema();
			Entity entity = new Entity(schema);
			double val = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble();
			int num = (int)AssistFunc.feetToMM(val);
			Field field = schema.GetField("Diameter");
			entity.Set<double>(field, (double)num, (Autodesk.Revit.DB.DisplayUnitType)6);
			double num2 = pipe.get_Parameter(BuiltInParameter.RBS_START_OFFSET_PARAM).AsDouble();
			Field field2 = schema.GetField("StartElevation");
            entity.Set<double>(field2, num2, (DisplayUnitType)6);
			double num3 = pipe.get_Parameter(BuiltInParameter.RBS_END_OFFSET_PARAM).AsDouble();
			Field field3 = schema.GetField("EndElevation");
            entity.Set<double>(field3, num3, (DisplayUnitType)6);
			Field field4 = schema.GetField("LegendScale");
            entity.Set<double>(field4, legendScale, (DisplayUnitType)6);
			curve.SetEntity(entity);
		}

		public static bool IsPipeDetailCurve(DetailLine line)
		{
			Guid guid = ExtensibleStorageManager.m_GUID;
			Schema schema = Schema.Lookup(guid);
			Entity entity = line.GetEntity(schema);
			return null != entity.Schema;
		}

		public static bool ReadPipeExtensibleStorageFromDetailCurve(DetailCurve curve, ref int diameter, ref double startElevation, ref double endElevation, ref double legendScale)
		{
			Guid guid = ExtensibleStorageManager.m_GUID;
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				return false;
			}
			Entity entity = curve.GetEntity(schema);
			if (entity.Schema == null)
			{
				return false;
			}
			double num = entity.Get<double>(schema.GetField("Diameter"), (Autodesk.Revit.DB.DisplayUnitType)6);
			diameter = (int)num;
			startElevation = entity.Get<double>(schema.GetField("StartElevation"), (Autodesk.Revit.DB.DisplayUnitType)6);
			startElevation = UnitConvert.LengthToInternal(startElevation);
			endElevation = entity.Get<double>(schema.GetField("EndElevation"), (Autodesk.Revit.DB.DisplayUnitType)6);
			endElevation = UnitConvert.LengthToInternal(endElevation);
			legendScale = entity.Get<double>(schema.GetField("LegendScale"), (Autodesk.Revit.DB.DisplayUnitType)6);
			return true;
		}

		private static Schema CreateModelInfoSchema()
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema != null)
			{
				return schema;
			}
			SchemaBuilder schemaBuilder = new SchemaBuilder(ExtensibleStorageManager.ModelInfoGuid);
			schemaBuilder.SetSchemaName("ModelInfo");
			schemaBuilder.AddSimpleField("IsPipe", typeof(bool));
			schemaBuilder.AddSimpleField("ModelId", typeof(int));
			schemaBuilder.AddSimpleField("ViewId", typeof(int));
			schemaBuilder.AddSimpleField("LinkId0", typeof(int));
			schemaBuilder.AddSimpleField("LinkId1", typeof(int));
			schemaBuilder.AddSimpleField("LinkId2", typeof(int));
			schemaBuilder.AddSimpleField("DetailGroups", typeof(string));
			return schemaBuilder.Finish();
		}

		internal static void WriteDetailGroupsInfo(Element elem, string detailGoups)
		{
			Schema schema = ExtensibleStorageManager.CreateModelInfoSchema();
			Entity entity = elem.GetEntity(schema);
			Field field = schema.GetField("DetailGroups");
			if (field != null && entity != null)
			{
				entity.Set<string>(field, detailGoups);
				elem.SetEntity(entity);
			}
		}

		internal static string ReadDetailGroupsInfo(Element elem)
		{
			string result = string.Empty;
			Schema schema = ExtensibleStorageManager.CreateModelInfoSchema();
			Entity entity = elem.GetEntity(schema);
			Field field = schema.GetField("DetailGroups");
			if (field != null && entity != null)
			{
				result = entity.Get<string>(field);
			}
			return result;
		}

		internal static void WriteModelInfo(Element elem, bool isPipe, ElementId viewId, ElementId modelId)
		{
			Schema schema = ExtensibleStorageManager.CreateModelInfoSchema();
			Entity entity = new Entity(schema);
			entity.Set<bool>("IsPipe", isPipe);
			entity.Set<int>("ViewId", viewId.IntegerValue);
			entity.Set<int>("ModelId", modelId.IntegerValue);
			elem.SetEntity(entity);
		}

		internal static void WriteModelInfo(Element elem, bool isPipe, ElementId viewId, ElementId modelId, List<ElementId> linkdeModelIds)
		{
			try
			{
				if (elem != null)
				{
					Schema schema = ExtensibleStorageManager.CreateModelInfoSchema();
					Entity entity = new Entity(schema);
					entity.Set<bool>("IsPipe", isPipe);
					entity.Set<int>("ViewId", viewId.IntegerValue);
					entity.Set<int>("ModelId", modelId.IntegerValue);
					if (linkdeModelIds.Count > 0)
					{
						entity.Set<int>("LinkId0", linkdeModelIds[0].IntegerValue);
					}
					if (linkdeModelIds.Count > 1)
					{
						entity.Set<int>("LinkId1", linkdeModelIds[1].IntegerValue);
					}
					if (linkdeModelIds.Count > 2)
					{
						entity.Set<int>("LinkId2", linkdeModelIds[2].IntegerValue);
					}
					elem.SetEntity(entity);
				}
			}
			catch
			{
			}
		}

		internal static bool GetModelInfo(this Element elem, out bool isPipe, out ElementId modelId, out IEnumerable<ElementId> linkdeModelIds)
		{
			isPipe = false;
			modelId = ElementId.InvalidElementId;
			linkdeModelIds = Enumerable.Empty<ElementId>();
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return false;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return false;
			}
			isPipe = entity.Get<bool>("IsPipe");
			modelId = new ElementId(entity.Get<int>("ModelId"));
			linkdeModelIds = from eId in new ElementId[]
			{
				new ElementId(entity.Get<int>("LinkId0")),
				new ElementId(entity.Get<int>("LinkId1")),
				new ElementId(entity.Get<int>("LinkId2"))
			}
			where eId != ElementId.InvalidElementId
			select eId;
			return true;
		}

		internal static IEnumerable<ElementId> GetLinkedModelIds(Element elem)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return null;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return null;
			}
			return from eId in new ElementId[]
			{
				new ElementId(entity.Get<int>("LinkId0")),
				new ElementId(entity.Get<int>("LinkId1")),
				new ElementId(entity.Get<int>("LinkId2"))
			}
			where eId != ElementId.InvalidElementId
			select eId;
		}

		internal static bool HasModelSchema(this Element elem)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return false;
			}
			Entity entity = elem.GetEntity(schema);
			return null != entity.Schema;
		}

		internal static ElementId GetViewId(this Element elem)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return ElementId.InvalidElementId;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return ElementId.InvalidElementId;
			}
			int num = entity.Get<int>("ViewId");
			return new ElementId(num);
		}

		internal static ElementId GetModelId(this Element elem)
		{
			ElementId invalidElementId = ElementId.InvalidElementId;
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return invalidElementId;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return invalidElementId;
			}
			int num = entity.Get<int>("ModelId");
			return new ElementId(num);
		}

        //[return: Dynamic]
		internal static dynamic GetViewAndModelId(this Element elem)
		{
			object obj = new ExpandoObject();
            //if (ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site5 == null)
            //{
            //    ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site5 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ViewId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site5.Target(ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site5, obj, ElementId.InvalidElementId);
            //if (ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site6 == null)
            //{
            //    ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site6 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ModelId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site6.Target(ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site6, obj, ElementId.InvalidElementId);
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return obj;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return obj;
			}
            //if (ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site7 == null)
            //{
            //    ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site7 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ViewId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site7.Target(ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site7, obj, new ElementId(entity.Get<int>("ViewId")));
            //if (ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site8 == null)
            //{
            //    ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site8 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ModelId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site8.Target(ExtensibleStorageManager.<GetViewAndModelId>o__SiteContainer4.<>p__Site8, obj, new ElementId(entity.Get<int>("ModelId")));
			return obj;
		}

		internal static IEnumerable<Element> GetElementsByView(this Document doc, View detailView)
		{
			if (Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid) == null)
			{
				return Enumerable.Empty<Element>();
			}
			ElementClassFilter item = new ElementClassFilter(typeof(CurveElement));
			ElementClassFilter item2 = new ElementClassFilter(typeof(TextNote));
			ElementClassFilter item3 = new ElementClassFilter(typeof(FilledRegion));
			List<ElementFilter> list = new List<ElementFilter>
			{
				item,
				item2,
				item3
			};
			LogicalOrFilter logicalOrFilter = new LogicalOrFilter(list);
			return from elem in new FilteredElementCollector(doc).WherePasses(logicalOrFilter).ToElements()
			where detailView.Id == elem.GetViewId()
			select elem;
		}

		internal static IEnumerable<Element> GetElementsByModelId(this Document doc, View View, ElementId modelId)
		{
			if (Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid) == null)
			{
				return Enumerable.Empty<Element>();
			}
			ElementClassFilter item = new ElementClassFilter(typeof(CurveElement));
			ElementClassFilter item2 = new ElementClassFilter(typeof(TextNote));
			ElementClassFilter item3 = new ElementClassFilter(typeof(FilledRegion));
			List<ElementFilter> list = new List<ElementFilter>
			{
				item,
				item2,
				item3
			};
			LogicalOrFilter logicalOrFilter = new LogicalOrFilter(list);
            return Enumerable.Empty<Element>();

            //return from <>h__TransparentIdentifierd in (from elem in new FilteredElementCollector(doc).WherePasses(logicalOrFilter).ToElements()
            //select new
            //{
            //    elem = elem,
            //    info = elem.GetViewAndModelId()
            //}).Where(delegate(<>h__TransparentIdentifierd)
            //{
            //    if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site10 == null)
            //    {
            //        ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site10 = CallSite<Func<CallSite, object, bool>>.Create(Binder.Convert(CSharpBinderFlags.None, typeof(bool), typeof(ExtensibleStorageManager)));
            //    }
            //    Func<CallSite, object, bool> target = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site10.Target;
            //    CallSite <>p__Site = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site10;
            //    if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site11 == null)
            //    {
            //        ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site11 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.None, ExpressionType.Equal, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //        }));
            //    }
            //    Func<CallSite, object, ElementId, object> target2 = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site11.Target;
            //    CallSite <>p__Site2 = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site11;
            //    if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site12 == null)
            //    {
            //        ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site12 = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, "ViewId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //        }));
            //    }
            //    object obj = target2(<>p__Site2, ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site12.Target(ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site12, <>h__TransparentIdentifierd.info), View.Id);
            //    if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site13 == null)
            //    {
            //        ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site13 = CallSite<Func<CallSite, object, bool>>.Create(Binder.UnaryOperation(CSharpBinderFlags.None, ExpressionType.IsFalse, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //        }));
            //    }
            //    object arg2;
            //    if (!ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site13.Target(ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site13, obj))
            //    {
            //        if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site14 == null)
            //        {
            //            ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site14 = CallSite<Func<CallSite, object, object, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.BinaryOperationLogical, ExpressionType.And, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //            {
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //            }));
            //        }
            //        Func<CallSite, object, object, object> target3 = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site14.Target;
            //        CallSite <>p__Site3 = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site14;
            //        object arg = obj;
            //        if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site15 == null)
            //        {
            //            ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site15 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.None, ExpressionType.Equal, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //            {
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //            }));
            //        }
            //        Func<CallSite, object, ElementId, object> target4 = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site15.Target;
            //        CallSite <>p__Site4 = ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site15;
            //        if (ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site16 == null)
            //        {
            //            ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site16 = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, "ModelId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //            {
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //            }));
            //        }
            //        arg2 = target3(<>p__Site3, arg, target4(<>p__Site4, ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site16.Target(ExtensibleStorageManager.<GetElementsByModelId>o__SiteContainerf.<>p__Site16, <>h__TransparentIdentifierd.info), modelId));
            //    }
            //    else
            //    {
            //        arg2 = obj;
            //    }
            //    return target(<>p__Site, arg2);
            //})
            //select <>h__TransparentIdentifierd.elem;
		}

		private static readonly Guid m_GUID = new Guid("406EB829-8264-42E9-A66F-685E5DA49189");

		private static readonly string m_schemaName = "HY_Plumbing_SystemDiagramNew_ESData";

		private static readonly Guid ModelInfoGuid = new Guid("{ACC0D869-C937-4B53-9F20-34BF313994E2}");

        //[CompilerGenerated]
        //private static class <GetViewAndModelId>o__SiteContainer4
        //{
        //    public static CallSite<Func<CallSite, object, ElementId, object>> <>p__Site5;

        //    public static CallSite<Func<CallSite, object, ElementId, object>> <>p__Site6;

        //    public static CallSite<Func<CallSite, object, ElementId, object>> <>p__Site7;

        //    public static CallSite<Func<CallSite, object, ElementId, object>> <>p__Site8;
        //}

        //[CompilerGenerated]
        //private static class <GetElementsByModelId>o__SiteContainerf
        //{
        //    public static CallSite<Func<CallSite, object, bool>> <>p__Site10;

        //    public static CallSite<Func<CallSite, object, ElementId, object>> <>p__Site11;

        //    public static CallSite<Func<CallSite, object, object>> <>p__Site12;

        //    public static CallSite<Func<CallSite, object, bool>> <>p__Site13;

        //    public static CallSite<Func<CallSite, object, object, object>> <>p__Site14;

        //    public static CallSite<Func<CallSite, object, ElementId, object>> <>p__Site15;

        //    public static CallSite<Func<CallSite, object, object>> <>p__Site16;
        //}
	}
}
